package com.javabase.y2021.m12.day1215;

import java.io.*;
import java.nio.CharBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;

/**
 * @descriptions:
 * @author: Tom
 * @date: 2021/12/15 上午 11:03
 * @version: 1.0
 */
public class Code02_FileChannelTest {
    public static void main(String[] args) {
        /**
         * Channel類似於傳統的流對象，但與傳統的流對象有主要區別
         * Channel可以直接將指定文件的部分或者全部映射成Buffer
         * 程序不能直接Channel中的數據，包括讀取和寫入都不行，Channel只能與Buffer進行交互
         * 如果要從Channel中讀取數據，必須先用Buffer從Channel中讀取一些數據，然後讓程序從Buffer
         * 中取出這些數據；
         * 如果要將程序中的數據寫入Channel，先讓程序將數據放入Buffer中，程序再將Buffer中的數據寫入Channel中
         * Java為Channel接口提供了DatagramChannel， FileChannel，Pipe.SinkChannel, Pipe.SourceChannel
         * SelectableChannel, ServerSocketChannel,SocketChannel
         */
        File f = new File("\\docker-compose.yml");
        try(
                // 創建FileInputStream,以該文件輸入流創建FileChannel
                FileChannel inChannel = new FileInputStream(f).getChannel();
                // 以文件輸出流創建FileChannel,用以控制輸出
                FileChannel outChannel = new FileOutputStream("a.txt").getChannel();
                ){
            // 將FileChannel裏面的全部數據映射成ByteBuffer
            MappedByteBuffer buffer = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, f.length());
            // 使用GBK的字符串來創建
            Charset charset = Charset.forName("GBK");
            // 直接將buffer裏的數據全部輸出
            outChannel.write(buffer);
            // 再次調用buffer的clear()方法，復原limit和position的位置
            buffer.clear();
            // 創建解碼器(CharsetDecoder)對象
            CharsetDecoder decoder = charset.newDecoder();
            // 使用解碼器將ByteBuffer轉換成CharBuffer
            CharBuffer charBuffer = decoder.decode(buffer);
            // CharBuffer的toString方法可以獲取對應的字符串
            System.out.println(charBuffer);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
